package com.xbongbong.paas.toolbox.util;

import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.enums.DateTimeEnum;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.pro.constant.DateConstant;
import com.xbongbong.pro.constant.I18nStringConstant;
import com.xbongbong.pro.enums.TimeTypeEnum;
import com.xbongbong.saas.constant.StringConstant;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Objects;
import java.util.regex.Pattern;

/**
 * 时间工具类
 *
 * <p>
 * 时间工具类拷贝自{@link DateUtil}
 * 主要用于处理时间转换。为了防止达到一定年份后时间戳转成int类型导致溢出问题，
 * 所以修改时间戳的类型使用long类型。其中一些int类型的历史方法均已标为废弃，并提供了替换方法，
 * 具体可以参看废弃方法的注释。另外，对于时间戳参数的规范和解释如下：
 * <ul>
 * <li>epochMilli：精确到毫秒的时间戳</li>
 * <li>epochSecond：精确到秒的时间戳</li>
 * </ul>
 * <p>
 *
 * @author GuoJun.HU
 * @date 2019/2/27 15:05
 * @since V1.0
 */
public final class DateTimeUtil {

    private static final Logger LOG = LoggerFactory.getLogger(DateTimeUtil.class);

    public static SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public static SimpleDateFormat SDF_NoFormat = new SimpleDateFormat("yyyyMMddHHmmss");
    public static SimpleDateFormat SDFYMDHM = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    public static SimpleDateFormat SDFDate = new SimpleDateFormat("yyyy-MM-dd");
    public static SimpleDateFormat SDFDate_NoFormat = new SimpleDateFormat("yyyyMMdd");
    public static SimpleDateFormat SDFYears = new SimpleDateFormat("yyyy");
    public static SimpleDateFormat SDFTime = new SimpleDateFormat("HH:mm:ss");
    public static SimpleDateFormat SDFMonthDay = new SimpleDateFormat("MM-dd");
    public static SimpleDateFormat SDFMonth = new SimpleDateFormat("yyyy-MM");
    public static SimpleDateFormat SDFHour_Minutes = new SimpleDateFormat("HH:mm");
    public static SimpleDateFormat SDFMDHM = new SimpleDateFormat("MM-dd HH:mm");
    public static SimpleDateFormat SDF_Z = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
    public static SimpleDateFormat SDFDate_Underline = new SimpleDateFormat("yyyy_MM_dd");

    /**
     * 获取精确到毫秒的时间戳
     *
     * @return 精确到毫秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 15:31
     * @since V1.0
     */
    public static long getLong() {
        Date dt = new Date();
        return dt.getTime();
    }
    /**
     * 获取精确到毫秒的时间戳
     *
     * @param date 日期
     * @return 精确到毫秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 15:31
     * @since V1.0
     */
    public static long getLong(Date date) {
        return date == null ? 0 : date.getTime();
    }

    /**
     * 获取精确到毫秒的时间戳
     *
     * @param dateString 日期字符串 格式:yyyy-MM-dd HH:mm
     * @return 精确到毫秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 15:31
     * @since V1.0
     */
    public static long getLong(String dateString) {
        return getLong(dateString, SDFYMDHM);
    }

    /**
     * 获取精确到毫秒的时间戳
     *
     * @param dateString 日期字符串
     * @param format     日期格式
     * @return 精确到毫秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 15:31
     * @since V1.0
     */
    public static long getLong(String dateString, SimpleDateFormat format) {
        if (StringUtil.isEmpty(dateString)) {
            return 0;
        }
        Date dt = getDate(dateString, format);
        return dt == null ? 0 : dt.getTime();
    }

    /**
     * 获取精确到毫秒的时间戳
     *
     * @param dateString 日期字符串
     * @param formatStr  日期格式
     * @return 精确到毫秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 15:31
     * @since V1.0
     */
    public static long getLong(String dateString, String formatStr) {
        return getLong(dateString, new SimpleDateFormat(formatStr));
    }

    /**
     * 获取当天00:00:00的精确到秒的时间戳
     * 东八区修正，与格林威治时间相差8个小时（28800秒）
     *
     * @return 精确到秒的时间戳（东八区修正）
     * @author GuoJun.HU
     * @date 2019/2/26 15:50
     * @since V1.0
     */
    public static long getTodayInt() {
        return getTodayInt(getInt());
    }

    /**
     * 获取某天00:00:00的精确到秒的时间戳
     * 东八区修正，与格林威治时间相差8个小时（28800秒）
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳（东八区修正）
     * @author GuoJun.HU
     * @date 2019/2/26 15:50
     * @since V1.0
     */
    public static long getTodayInt(long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(epochSecond * 1000L);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTimeInMillis() / 1000L;
    }
    /**
     * 获取当天23:59:59 ，东八区修正，与格林威治时间相差8个小时 28800秒
     * @return
     */
    public static long getTodayEndInt(long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(epochSecond * 1000L);
        calendar.set(Calendar.HOUR_OF_DAY,23);
        calendar.set(Calendar.MINUTE,59);
        calendar.set(Calendar.SECOND,59);
        return calendar.getTimeInMillis() / 1000L;
    }

    /**
     * 根据时间类型返回当前时间的时间戳
     * @param dateType 日期类型
     * @see DateTimeEnum
     * @return 精确到0秒的时间戳
     */
    public static long getThisIntByDateType(String dateType) {
        SimpleDateFormat format = new SimpleDateFormat(dateType);
        String date = getString(format);
        return getInt(date, format);
    }

    /**
     * 获取精确到秒的时间戳
     *
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 15:31
     * @since V1.0
     */
    public static long getInt() {
        return getLong() / 1000;
    }

    /**
     * 获取精确到秒的时间戳
     *
     * @param date 日期
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 15:31
     * @since V1.0
     */
    public static long getInt(Date date) {
        return getLong(date) / 1000;
    }

    /**
     * 获取精确到秒的时间戳
     *
     * @param dateString 日期字符串 格式:yyyy-MM-dd HH:mm
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 15:31
     * @since V1.0
     */
    public static long getInt(String dateString) {
        return getLong(dateString) / 1000;
    }

    /**
     * 获取精确到秒的时间戳
     *
     * @param dateString 日期字符串
     * @param format     日期格式
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 15:31
     * @since V1.0
     */
    public static long getInt(String dateString, SimpleDateFormat format) {
        return getLong(dateString, format) / 1000;
    }

    /**
     * 获取精确到秒的时间戳
     *
     * @param dateString 日期字符串
     * @param formatStr  日期格式
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 15:31
     * @since V1.0
     */
    public static long getInt(String dateString, String formatStr) {
        return getInt(dateString, new SimpleDateFormat(formatStr));
    }

    /**
     * 获取某个时间点所在月份的某天的时间（小时、分、秒与传入的epochSecond一致）
     * 即：同年、同月、【不同天(天用day，超过最后一天则用月末)】、同时分秒
     * @param epochSecond 精确到秒的时间戳
     * @param day 某一天
     * @return long
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public static final long getIntTimeOfDay(Long epochSecond, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        //处理最后一天问题
        calendar.set(Calendar.DATE, 1);
        calendar.roll(Calendar.DATE, -1);
        int totalDay =  calendar.get(Calendar.DATE);
        //如果day超过了当月最大天数，则默认置为当月最后一天（月末）的0点
        if (day > totalDay) {
            day = totalDay;
        }
        //同年、同月、【不同天】、同时分秒
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), day, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取某个时间点所在年的某月某天的时间（小时、分、秒与传入的epochSecond一致）
     * 即：同年、【不同月(月用month)】、【不同天(天用day，超过最后一天则用月末)】、同时分秒
     * @param epochSecond 精确到秒的时间戳
     * @param month 某月
     * @param day 某一天
     * @return long
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public static final long getIntTimeOfMonthDay(Long epochSecond, int month, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        //处理最后一天问题
        calendar.set(Calendar.MONTH, month - 1);
        calendar.set(Calendar.DATE, 1);
        calendar.roll(Calendar.DATE, -1);
        int totalDay =  calendar.get(Calendar.DATE);
        //如果day超过了当月最大天数，则默认置为当月最后一天（月末）的0点
        if (day > totalDay) {
            day = totalDay;
        }
        //同年、同月、【不同天】、同时分秒
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), day, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取当前年份
     *
     * @return 当前年份
     * @author GuoJun.HU
     * @date 2019/2/26 15:58
     * @since V1.0
     */
    public static int getNowSDFYears() {
        return StringUtil.stringToInteger(SDFYears.format(new Date()), 0);
    }

    /**
     * 获取当前格式化的时间
     *
     * @param format 格式化方式
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    public static String getString(SimpleDateFormat format) {
        return format.format(new Date());
    }

    /**
     * 获取当前格式化的时间
     *
     * @param formatStr 格式化方式
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    public static String getString(String formatStr) {
        return getString(new SimpleDateFormat(formatStr));
    }

    /**
     * 获取格式化的时间
     *
     * @param dt     需要格式化的日期
     * @param format 格式化方式
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    public static String getString(Date dt, SimpleDateFormat format) {
        return dt == null ? null : format.format(dt);
    }

    /**
     * 获取格式化的时间
     *
     * @param dt        需要格式化的日期
     * @param formatStr 格式化方式
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    public static String getString(Date dt, String formatStr) {
        return getString(dt, new SimpleDateFormat(formatStr));
    }

    /**
     * 获取格式化的时间
     *
     * @param epochMilli 需要格式化的时间 精确到毫秒的时间戳
     * @param format     格式化方式
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    public static String getString(Long epochMilli, SimpleDateFormat format) {
        if (epochMilli == null) {
            return null;
        }
        if (epochMilli == 0) {
            return "";
        }
        return format.format(new Date(epochMilli));
    }

    /**
     * 获取格式化的时间
     *
     * @param epochMilli 需要格式化的时间 精确到毫秒的时间戳
     * @param formatStr  格式化方式
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    public static String getString(Long epochMilli, String formatStr) {
        epochMilli = epochMilli == null ? null : 1000* epochMilli;
        return getString(epochMilli, new SimpleDateFormat(formatStr));
    }

    /**
     * 获取格式化的时间
     * 废弃
     * 替换方法{@link DateTimeUtil#getStringEpochSecond(Long, SimpleDateFormat)}
     *
     * @param epochSecond 需要格式化的时间 精确到秒的时间戳
     * @param format      格式化方式
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    @Deprecated
    public static String getString(Integer epochSecond, SimpleDateFormat format) {
        return epochSecond == null ? null : getString(1000L * epochSecond, format);
    }

    /**
     * 获取格式化的时间
     *
     * @param epochSecond 需要格式化的时间 精确到秒的时间戳
     * @param format      格式化方式
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    public static String getStringEpochSecond(Long epochSecond, SimpleDateFormat format) {
        return epochSecond == null || epochSecond == 0 ? null : getString(1000L * epochSecond, format);
    }

    /**
     * 获取格式化的时间
     * 废弃
     * 替换方法{@link DateTimeUtil#getStringEpochSecond(Long, String)}
     *
     * @param epochSecond 需要格式化的时间 精确到秒的时间戳
     * @param formatStr   格式化方式
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    @Deprecated
    public static String getString(Integer epochSecond, String formatStr) {
        return getString(epochSecond, new SimpleDateFormat(formatStr));
    }

    /**
     * 获取格式化的时间
     *
     * @param epochSecond 需要格式化的时间 精确到秒的时间戳
     * @param formatStr   格式化方式
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    public static String getStringEpochSecond(Long epochSecond, String formatStr) {
        return getStringEpochSecond(epochSecond, new SimpleDateFormat(formatStr));
    }

    /**
     * 获取当前格式化的时间 格式：yyyy-MM-dd HH:mm
     *
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    public static String getString() {
        return getString(SDFYMDHM);
    }

    /**
     * 获取格式化的时间 格式：yyyy-MM-dd HH:mm:ss
     *
     * @param dt 要格式化的时间
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    public static String getString(Date dt) {
        return getString(dt, SDF);
    }

    /**
     * 获取格式化的时间 格式：yyyy-MM-dd HH:mm
     *
     * @param epochMilli 要格式化的时间 精确到毫秒的时间戳
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    public static String getString(long epochMilli) {
        return getString(epochMilli, SDFYMDHM);
    }

    /**
     * 获取格式化的时间 格式：yyyy-MM-dd HH:mm
     * 废弃
     * 替换方法{@link DateTimeUtil#getStringEpochSecond(long)}
     *
     * @param epochSecond 要格式化的时间 精确到秒的时间戳
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 16:51
     * @since V1.0
     */
    @Deprecated
    public static String getString(int epochSecond) {
        return getString(epochSecond, SDFYMDHM);
    }

    /**
     * 获取格式化的时间 格式：yyyy-MM-dd HH:mm
     *
     * @param epochSecond 需要格式化的时间 精确到秒的时间戳
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    public static String getStringEpochSecond(long epochSecond) {
        return getStringEpochSecond(epochSecond, SDFYMDHM);
    }

    /**
     * 获取格式化的时间 格式：yyyy-MM-dd
     * 废弃
     * 替换方法{@link DateTimeUtil#getDateStringEpochSecond(long)}
     *
     * @param epochSecond 需要格式化的时间 精确到秒的时间戳
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    @Deprecated
    public static String getDateString(int epochSecond) {
        return getString(epochSecond, SDFDate);
    }

    /**
     * 获取格式化的时间
     *
     * @param epochSecond 需要格式化的时间 精确到秒的时间戳
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 15:59
     * @since V1.0
     */
    public static String getDateStringEpochSecond(long epochSecond) {
        return getStringEpochSecond(epochSecond, SDFDate);
    }

    /**
     * 获取格式化的时间
     *
     * @param time 需要格式化的日期
     * @return 格式化的时间
     * @author GuoJun.HU
     * @date 2019/2/26 21:18
     * @since V1.0
     */
    public static String getDateString(Date time) {
        return getString(time, SDFDate);
    }

    public static String getLeftTime(long startTimeEpochSecond, long limitTimeEpochSecond) {
        String leftTime = null;
        long now = DateTimeUtil.getInt();
        long differenceTime = now - startTimeEpochSecond;
        if (differenceTime >= 0) {
            long leftTimeInt = limitTimeEpochSecond - differenceTime;
            if (leftTimeInt < 0) {
                leftTimeInt = 0;
            }
            String h = (leftTimeInt / 3600) + "";
            String m = (leftTimeInt % 3600) / 60 + "";
            leftTime = h + I18nMessageUtil.getMessage(CommonConstant.HOUR) + m + I18nMessageUtil.getMessage(CommonConstant.MINUTE);
        }
        return leftTime;
    }

    /**
     * 时间戳转时间
     *
     * @param epochMilli 精确到毫秒的时间戳
     * @return 时间对象
     * @author GuoJun.HU
     * @date 2019/2/26 21:35
     * @since V1.0
     */
    public static Date getDate(Long epochMilli) {
        return epochMilli == null ? null : new Date(epochMilli);
    }

    /**
     * 时间戳转时间
     * 废弃 替换方法{@link DateTimeUtil#getDateEpochSecond(Long)}
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 时间对象
     * @author GuoJun.HU
     * @date 2019/2/26 21:35
     * @since V1.0
     */
    @Deprecated
    public static Date getDate(Integer epochSecond) {
        return epochSecond == null ? null : new Date(1000L * epochSecond);
    }

    /**
     * 时间戳转时间
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 时间对象
     * @author GuoJun.HU
     * @date 2019/2/26 21:35
     * @since V1.0
     */
    public static Date getDateEpochSecond(Long epochSecond) {
        return epochSecond == null ? null : new Date(1000L * epochSecond);
    }

    /**
     * 获取当前时间
     *
     * @return 时间对象
     * @author GuoJun.HU
     * @date 2019/2/26 21:35
     * @since V1.0
     */
    public static Date getDate() {
        return new Date();
    }

    /**
     * 将格式化后的时间转成时间对象
     *
     * @param dateString 格式化后的时间
     * @param format     格式化方式
     * @return 时间对象
     * @author GuoJun.HU
     * @date 2019/2/26 21:48
     * @since V1.0
     */
    public static Date getDate(String dateString, SimpleDateFormat format) {
        if (StringUtil.isEmpty(dateString)) {
            return null;
        }
        try {
            return format.parse(dateString);
        } catch (ParseException e) {
            LOG.error(e.getMessage());
            return null;
        }
    }

    /**
     * 将格式化后的时间转成时间对象
     * 格式化方式：yyyy-MM-dd HH:mm
     *
     * @param dateString 格式化后的时间
     * @return 时间对象
     * @author GuoJun.HU
     * @date 2019/2/26 21:48
     * @since V1.0
     */
    public static Date getDate(String dateString) {
        return getDate(dateString, SDFYMDHM);
    }

    /**
     * 获取当前年份1月1日0点0时0分
     *
     * @return
     * @author GuoJun.HU
     * @date 2019/2/26 22:11
     * @since V1.0
     */
    public static final long getFirstDateOfYear() {
        return getFirstDateOfYear(getInt());
    }

    /**
     * 获取当前年份12月31日23点59时59分 即 下一年的1月1日0点0时0分
     *
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 22:09
     * @since V1.0
     */
    public static final long getLastDateOfYear() {
        return getLastDateOfYear(getInt());
    }

    /**
     * 获取当前年份1月1日0点0时0分
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 22:08
     * @since V1.0
     */
    public static final long getFirstDateOfYear(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR), Calendar.JANUARY, 1, 0, 0, 0);
        return (calendar.getTimeInMillis()) / 1000;
    }

    /**
     * 获取前一年的1月1日0点0时0分
     *
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 22:07
     * @since V1.0
     */
    public static final long getFirstDateOfPreviousYear() {
        return getFirstDateOfPreviousYear(getInt());
    }

    /**
     * 获取前一年的1月1日0点0时0分
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 21:57
     * @since V1.0
     */
    public static final long getFirstDateOfPreviousYear(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR) - 1, Calendar.JANUARY, 1, 0, 0, 0);
        return (calendar.getTimeInMillis()) / 1000;
    }

    /**
     * 获取当前年份12月31日23点59时59分 即 下一年的1月1日0点0时0分
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 21:57
     * @since V1.0
     */
    public static final long getLastDateOfYear(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR) + 1, Calendar.JANUARY, 1, 0, 0, 0);
        return (calendar.getTimeInMillis()) / 1000;
    }

    /**
     * 获取下一年12月31日23点59时59分 即 下下一年的1月1日0点0时0分
     *
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 22:09
     * @since V1.0
     */
    public static final long getLastDateOfNextYear() {
        return getLastDateOfNextYear(getInt());
    }

    /**
     * 获取下一年12月31日24点59时59分 即 下下一年的1月1日0点0时0分
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 21:57
     * @since V1.0
     */
    public static final long getLastDateOfNextYear(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR) + 2, Calendar.JANUARY, 1, 0, 0, 0);
        return (calendar.getTimeInMillis()) / 1000;
    }

    /**
     * 获取当前年份第一季度结束时间
     *
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 21:57
     * @since V1.0
     */
    public static final long getLastDateOfFirstSeason() {
        return getLastDateOfFirstSeason(getInt());
    }

    /**
     * 获取当前年份第一季度结束时间
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/26 21:57
     * @since V1.0
     */
    public static final long getLastDateOfFirstSeason(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR), Calendar.APRIL, 1, 0, 0, 0);
        return (calendar.getTimeInMillis()) / 1000;
    }

    /**
     * 获取季度
     * 1 第一季度
     * 2 第二季度
     * 3 第三季度
     * 4 第四季度
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 季度
     * @author GuoJun.HU
     * @since V1.0
     */
    public static int getSeason(Long epochSecond) {
        int season = 0;

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        int month = calendar.get(Calendar.MONTH);
        switch (month) {
            case Calendar.JANUARY:
            case Calendar.FEBRUARY:
            case Calendar.MARCH:
                season = 1;
                break;
            case Calendar.APRIL:
            case Calendar.MAY:
            case Calendar.JUNE:
                season = 2;
                break;
            case Calendar.JULY:
            case Calendar.AUGUST:
            case Calendar.SEPTEMBER:
                season = 3;
                break;
            case Calendar.OCTOBER:
            case Calendar.NOVEMBER:
            case Calendar.DECEMBER:
                season = 4;
                break;
            default:
                break;
        }

        return season;
    }
    
    /**
     * 获得当前季度的第一天
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:39
     * @since V1.0
     */
    public static long getFirstDateOfSeason(Long epochSecond) {
        int m = Calendar.JANUARY;

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        int month = calendar.get(Calendar.MONTH);
        switch (month) {
            case Calendar.JANUARY:
            case Calendar.FEBRUARY:
            case Calendar.MARCH:
                m = Calendar.JANUARY;
                break;
            case Calendar.APRIL:
            case Calendar.MAY:
            case Calendar.JUNE:
                m = Calendar.APRIL;
                break;
            case Calendar.JULY:
            case Calendar.AUGUST:
            case Calendar.SEPTEMBER:
                m = Calendar.JULY;
                break;
            case Calendar.OCTOBER:
            case Calendar.NOVEMBER:
            case Calendar.DECEMBER:
                m = Calendar.OCTOBER;
                break;
            default:
                break;
        }
        calendar.set(calendar.get(Calendar.YEAR), m, 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获得当前季度的最后一天
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @since V1.0
     */
    public static long getLastDateOfSeason(Long epochSecond) {
        int m = Calendar.JANUARY;

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        int month = calendar.get(Calendar.MONTH);
        switch (month) {
            case Calendar.JANUARY:
            case Calendar.FEBRUARY:
            case Calendar.MARCH:
                m = Calendar.APRIL;
                break;
            case Calendar.APRIL:
            case Calendar.MAY:
            case Calendar.JUNE:
                m = Calendar.JULY;
                break;
            case Calendar.JULY:
            case Calendar.AUGUST:
            case Calendar.SEPTEMBER:
                m = Calendar.OCTOBER;
                break;
            case Calendar.OCTOBER:
            case Calendar.NOVEMBER:
            case Calendar.DECEMBER:
                m = Calendar.JANUARY;
                break;
            default:
                break;
        }

        int year = calendar.get(Calendar.YEAR);
        //第四季度截止时间跨年问题
        if (m == 0) {
            year = year + 1;
        }
        calendar.set(year, m, 1, 0, 0, 0);

        return calendar.getTimeInMillis() / 1000;
    }
    
    /**
     * 获取下季度的第一天
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @since V1.0
     */
    public static long getFirstDateOfNextSeason(Long epochSecond) {
        return getLastDateOfSeason(epochSecond);
    }
    
    
    /**
     * 获取下季度的最后一天
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @since V1.0
     */
    public static long getLastDateOfNextSeason(Long epochSecond) {
        int m = Calendar.JANUARY;

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        int month = calendar.get(Calendar.MONTH);
        switch (month) {
            case Calendar.JANUARY:
            case Calendar.FEBRUARY:
            case Calendar.MARCH:
                m = Calendar.JULY;
                break;
            case Calendar.APRIL:
            case Calendar.MAY:
            case Calendar.JUNE:
                m = Calendar.OCTOBER;
                break;
            case Calendar.JULY:
            case Calendar.AUGUST:
            case Calendar.SEPTEMBER:
                m = Calendar.JANUARY;
                break;
            case Calendar.OCTOBER:
            case Calendar.NOVEMBER:
            case Calendar.DECEMBER:
                m = Calendar.APRIL;
                break;
            default:
                break;
        }

        int year = calendar.get(Calendar.YEAR);
        // 跨年问题
        if (m == Calendar.JANUARY || m == Calendar.APRIL ) {
            year = year + 1;
        }
        calendar.set(year, m, 1, 0, 0, 0);

        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获得上个季度的第一天
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:39
     * @since V1.0
     */
    public static long getFirstDateOfLastSeason(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(getFirstDateOfSeason(epochSecond)*1000);
        calendar.add(Calendar.MONTH,-3);
        return calendar.getTimeInMillis()/1000;
    }

    /**
     * 获得上个季度的最后一天
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @since V1.0
     */
    public static long getLastDateOfLastSeason(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(getLastDateOfSeason(epochSecond)*1000);
        calendar.add(Calendar.MONTH,-3);
        return calendar.getTimeInMillis()/1000;
    }

    /**
     * 获取当前月份的1日0时0分0秒
     *
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:45
     * @since V1.0
     */
    public static final long getFirstDateOfThisMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取某天所在月份的1日0时0分0秒
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getFirstDateOfMonthInSomeday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 同比， 获取上年同月的第一天
     * 比如传入的时间是2016年6月，则该方法得到2015年6月1日0时0分0秒
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getFirstDateOfLastYear(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR) - 1, calendar.get(Calendar.MONTH), 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 同比，获取上年同月的最后一天
     * 比如传入的时间是2016年6月，则该方法得到2015年7月1日0时0分0秒（即6月末）
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getLastDateOfLastYear(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR) - 1, calendar.get(Calendar.MONTH) + 1, 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取某天所在月份下个月的1日0时0分0秒
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getLastDateOfMonthInSomeday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取某天所在时间的下个月1号的同分同秒（非0点）
     * @param epochSecond
     * @return long
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public static final long getNextTimeOfMonthInSomeday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, 1, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取某天所在时间的下年同月1号的同分同秒（非0点）
     * @param epochSecond
     * @return long
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public static final long getNextTimeOfYearInSomeday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR) + 1, calendar.get(Calendar.MONTH), 1, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), calendar.get(Calendar.SECOND));
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取当前月份的上一个月份的1日0时0分0秒
     *
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getFirstDateOfLastMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) - 1, 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }
    /**
     * 获取某天上个月份的最后一天的24时0分0秒
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author MengNa.DENG
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getLastDateOfLastMonth(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) , 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取某天所在月份的上一个月份的1日0时0分0秒
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getFirstDateOfLastMonth(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) - 1, 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取当前月份的最后一天的24时24分24秒 即 下一个月的1日0时0分0秒
     *
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getLastDateOfThisMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1, 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取某天所在月份的最后一天的23时59分59秒
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     */
    public static long getLastDateOfThisMonthInSomeday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        //设置年份
        calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
        //设置月份
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH));
        //获取某月最大天数
        int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        //设置日历中月份的最大天数
        calendar.set(Calendar.DAY_OF_MONTH, lastDay);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取某天所在月份的下一个月的最后一天的23时59分59秒 即 下两个个月的1日0时0分0秒
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getLastDateOfNextMonthInSomeday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 2, 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取今年2月1日的0时0分0秒     用于推算其他月份的时间
     *
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getFirstDateOfFeb() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), 1, 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取今年3月1日的0时0分0秒     用于推算其他月份的时间
     *
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getFirstDateOfMar() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), 2, 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获得本周一0点时间
     *
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 11:04
     * @since V1.0
     */
    public static long getThisWeekMorning() {
        return getWeekMorningInSomeday(getInt());
    }

    /**
     * 获取某天所在周的周一的0点
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getWeekMorningInSomeday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), 0, 0, 0);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (dayOfWeek == 0) {
            dayOfWeek = 7;
        }
        calendar.add(Calendar.DATE, -dayOfWeek + 1);
        return calendar.getTimeInMillis() / 1000;
    }
    
    /**
     * 获取某天所在周的周日24点 即下周一0点
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getWeekSundayInSomeday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), 0, 0, 0);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (dayOfWeek == 0) {
            dayOfWeek = 7;
        }
        calendar.add(Calendar.DATE, -dayOfWeek + 1 + 7);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取某天所在周的周日的23时59分59秒
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     */
    public static long getSundayInSomeday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        //以周一为首
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(new Date(epochSecond * 1000));
        //设置年份
        calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
        //设置月份
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH));
        //周日
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取某天所在周上一周的周一0点
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getLastWeekMondayInSomeday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), 0, 0, 0);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (dayOfWeek == 0) {
            dayOfWeek = 7;
        }
        calendar.add(Calendar.DATE, -dayOfWeek + 1 - 7);
        return calendar.getTimeInMillis() / 1000;
    }
    
    /**
     * 获取某天所在周下一周周日24点 即下下周一0点
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 10:46
     * @since V1.0
     */
    public static final long getNextWeekSundayInSomeday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), 0, 0, 0);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (dayOfWeek == 0) {
            dayOfWeek = 7;
        }
        calendar.add(Calendar.DATE, -dayOfWeek + 1 + 14);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 从现在向上推一个月时间的零点
     * @return
     */
    public static long getLastMonthFromTodayInt(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(1000 * getTodayInt());
        calendar.add(Calendar.MONTH,-1);
        return calendar.getTimeInMillis()/1000;
    }

    /**
     * 获取某一天在一周内的最后一天
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author 魏荣杰
     * @date 2018/3/21 19:03
     * @since v3.19
     */
    public static final long getWeekLastDayInSomeday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date((long) (epochSecond) * 1000));
        calendar.setFirstDayOfWeek(Calendar.MONTH);
        calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek() + 6);
        return calendar.getTimeInMillis() / 1000 + 86400;
    }

    /**
     * 获取某天所在周是周几， 0-6,代表周日到周六
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 周几
     * @author 魏荣杰
     * @date 2018/3/21 19:03
     * @since v3.19
     */
    public static final Integer getWeekInSomeday(Long epochSecond) {
        if (Objects.isNull(epochSecond)) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        int week = calendar.get(Calendar.DAY_OF_WEEK);
        return week - 1;
    }

    /**
     * 获取某天所在周是周几， 1-7,代表周一到周日
     *
     * @param epochSecond 精确到秒的时间戳
     * @return java.lang.Integer 周几
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public static final Integer getWeekInSomeday4Normal(Long epochSecond) {
        int week = getWeekInSomeday(epochSecond);
        week = week == 0 ? 7 : week;
        return week;
    }

    /**
     * 获取某个月有多少天
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 天数
     * @author 魏荣杰
     * @date 2018/3/21 19:03
     * @since v3.19
     */
    public static final int getDaysOfSomeMonth(Long epochSecond) {
        Date date = new Date(epochSecond * 1000);
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取某个月有多少周
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 多少周
     * @author 魏荣杰
     * @date 2018/3/21 19:03
     * @since v3.19
     */
    public static final int getWeeksOfSomeMonth(Long epochSecond) {
        Date date = new Date(epochSecond * 1000);
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        return calendar.getActualMaximum(Calendar.WEEK_OF_MONTH);
    }

    /**
     * 获取某天是该月的第几周
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 第几周
     * @author 魏荣杰
     * @date 2018/3/21 19:03
     * @since v3.19
     */
    public static final int getWeekOfMonth(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        return calendar.get(Calendar.WEEK_OF_MONTH);
    }

    /**
     * 获取某天是该年的第几周
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 第几周
     * @author 魏荣杰
     * @date 2018/3/21 19:03
     * @since v3.19
     */
    public static final int getWeekOfYear(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.SUNDAY);
        calendar.setTime(new Date(epochSecond * 1000));
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 获取某天是该年的第几周
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 第几周
     * @author 魏荣杰
     * @date 2018/3/21 19:03
     * @since v3.19
     */
    public static final int getWeekOfYear(Long epochSecond, Integer value) {
        Calendar calendar = Calendar.getInstance();
        if (Objects.nonNull(value)) {
            calendar.setFirstDayOfWeek(value);
        }
        calendar.setTime(new Date(epochSecond * 1000));
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }
    /**
     * 获取某天是该年的第几周
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 第几周
     * @author 魏荣杰
     * @date 2018/3/21 19:03
     * @since v3.19
     */
    public static final int getWeekOfYearMax(Long epochSecond, Integer value) {
        Calendar calendar = Calendar.getInstance();
        if (Objects.nonNull(value)) {
            calendar.setFirstDayOfWeek(value);
        }
        calendar.setTime(new Date(epochSecond * 1000));
        return calendar.getMaximum(Calendar.WEEK_OF_YEAR);
    }

    /**
     * 获得两个时间点之间跨度几月
     * 例如：2015-5-12 2015-5-15 跨度0个月
     *
     * @param startTimeEpochSecond 起始时间 精确到秒的时间戳
     * @param endTimeEpochSecond   结束时间 精确到秒的时间戳
     * @return 跨度几月
     * @author GuoJun.HU
     * @date 2019/2/27 11:15
     * @since V1.0
     */
    public static final int getMonthBetweenSomeday(Long startTimeEpochSecond, Long endTimeEpochSecond) {
        Date startDate = new Date(startTimeEpochSecond * 1000);
        Date endDate = new Date(endTimeEpochSecond * 1000);
        int yearNum = endDate.getYear() - startDate.getYear();
        int monthNum = endDate.getMonth() - startDate.getMonth();
        return yearNum * 12 + monthNum;
    }

    /**
     * 获得两个时间点之间跨度几季度
     * 例如：2015-5-12 2015-5-15 return 0
     *
     * @param startTimeEpochSecond 起始时间 精确到秒的时间戳
     * @param endTimeEpochSecond   结束时间 精确到秒的时间戳
     * @return 跨度几季度
     * @author GuoJun.HU
     * @date 2019/2/27 11:15
     * @since V1.0
     */
    public static final int getSeasonBetweenSomeday(Long startTimeEpochSecond, Long endTimeEpochSecond) {
        Date startDate = new Date(startTimeEpochSecond * 1000);
        Date endDate = new Date(endTimeEpochSecond * 1000);
        int yearNum = endDate.getYear() - startDate.getYear();
        int seasonNum = getSeason(endTimeEpochSecond) - getSeason(startTimeEpochSecond);
        return yearNum * 4 + seasonNum;
    }

    /**
     * 获得两个时间点之间跨度几年
     * 例如：2015-5-12 2015-5-15 return 0
     *
     * @param startTimeEpochSecond 起始时间 精确到秒的时间戳
     * @param endTimeEpochSecond   结束时间 精确到秒的时间戳
     * @return 跨度几年
     * @author GuoJun.HU
     * @date 2019/2/27 11:15
     * @since V1.0
     */
    public static final int getYearBetweenSomeday(Long startTimeEpochSecond, Long endTimeEpochSecond) {
        Date startDate = new Date(startTimeEpochSecond * 1000);
        Date endDate = new Date(endTimeEpochSecond * 1000);
        return endDate.getYear() - startDate.getYear();
    }

    /**
     * 获得两个时间点之间已满几个月
     *
     * @param startTimeEpochSecond 起始时间 精确到秒的时间戳
     * @param endTimeEpochSecond   结束时间 精确到秒的时间戳
     * @return 已满几个月
     * @author GuoJun.HU
     * @date 2019/2/27 11:15
     * @since V1.0
     */
    public static final int getMonthNum(Long startTimeEpochSecond, Long endTimeEpochSecond) {
        Date startDate = new Date(startTimeEpochSecond * 1000);
        Date endDate = new Date(endTimeEpochSecond * 1000);
        int yearNum = endDate.getYear() - startDate.getYear();
        int monthNum = endDate.getMonth() - startDate.getMonth();
        int dayNum = endDate.getDate() - startDate.getDate();

        int ret = yearNum * 12 + monthNum;
        if (dayNum < 0) {
            ret = ret - 1;
        }
        return ret;
    }

    /**
     * 返回年份
     * 如 2015
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 年份
     */
    public static String getYear(Long epochSecond) {
        return epochSecond == null ? null : getString(epochSecond*1000).substring(0, 4);
    }

    /**
     * 获取某个时间的年份
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 年份
     * @version performance-v1.0
     * @author chuanpeng.zhang
     * 创建时间：2018年10月16日 下午5:31:58
     * @since performance-v1.0
     */
    public static int getYear4Someday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 返回月 如 04
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 月份
     */
    public static String getMonth(Long epochSecond) {
        return epochSecond == null ? null : getString(epochSecond * 1000).substring(5, 7);
    }

    /**
     * 获取某个时间的月份
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 月份
     * @version performance-v1.0
     * @author chuanpeng.zhang
     * 创建时间：2018年10月16日 下午5:30:34
     * 修改时间：
     * @since performance-v1.0
     */
    public static int getMonth4Someday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 返回日 如 14
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 日
     */
    public static String getDay(Long epochSecond) {
        return epochSecond == null ? null : getString(epochSecond*1000).substring(8, 10);
    }

    /**
     * 获取某个时间的日期
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 日期
     * @version performance-v1.0
     * @author chuanpeng.zhang
     * 创建时间：2018年10月16日 下午5:33:15
     * 修改时间：
     * @since performance-v1.0
     */
    public static int getDay4Someday(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 返回 HH:mm
     *
     * @param epochSecond 精确到秒的时间戳
     * @return HH:mm
     */
    public static String getHour(Long epochSecond) {
        String stringEpochSecond = getStringEpochSecond(epochSecond);
        if (Objects.isNull(stringEpochSecond)) {
            return null;
        }
        return stringEpochSecond.substring(11);
    }

    /**
     * 返回 HH:mm:ss
     *
     * @param epochSecond 精确到秒的时间戳
     * @return java.lang.String HH:mm:ss
     * @author zcp
     * @since v1.0
     * @version v1.0
     */
    public static String getHourMinSecond(Long epochSecond) {
        return epochSecond == null ? null : getStringEpochSecond(epochSecond, SDF).substring(11);
    }
    /**
     * 获取某个时间的小时
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 小时（24小时制）
     * @version v1.0
     * @author 吴峰
     * 创建时间：2019年12月30日 下午5:33:15
     * 修改时间：
     */
    public static Integer getHourSomeday(Long epochSecond) {
        if (Objects.isNull(epochSecond)) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        return calendar.get(Calendar.HOUR_OF_DAY);
    }
    /**
     * 获取某个时间的分钟
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 分钟
     * @version v1.0
     * @author 吴峰
     */
    public static Integer getMinuteSomeday(Long epochSecond) {
        if (Objects.isNull(epochSecond)) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        return calendar.get(Calendar.MINUTE);
    }

    /**
     *
     * @author 吴峰
     * @date 2019/12/31 11:02
     * @param epochSecond 精确到秒的时间戳
     * @return int
     */
    public static Integer getSecondSomeday(Long epochSecond) {
        if (Objects.isNull(epochSecond)) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        return calendar.get(Calendar.SECOND);
    }
    /**
     * 开始时间+一段毫秒数
     *
     * @param start      起始时间
     * @param epochMilli 精确到毫秒的时间戳
     * @return 日期
     * @author GuoJun.HU
     * @date 2019/2/27 11:27
     * @since V1.0
     */
    public static Date addDate(Date start, long epochMilli) {
        return new Date(start.getTime() + epochMilli);
    }

    /**
     * 获得一个前num个周一的日期数组，如：{"2015-4-26",...,"2015-3-15"}
     *
     * @param num 多少个周一
     * @return 日期数组
     */
    public static String[] getWeekArray(Integer num) {
        String[] weekArray = new String[num];
        Long weekInt = getThisWeekMorning();

        for (int i = 0; i < num; i++) {
            long week = weekInt - 86400 * 7 * i;
            weekArray[i] = getDateStringEpochSecond(week);
        }
        return weekArray;
    }

    /**
     * 获得前num个月的1月1号，如：{"2015-4-1",......,"2014-1-1"}
     *
     * @param num 多少月
     * @return 日期数组
     */
    public static String[] getMonthArray(Integer num) {
        String[] monthArray = new String[num];
        long now = getInt();
        for (int i = 0; i < num; i++) {
            now = getFirstDateOfLastMonth(now);
            monthArray[i] = getDateStringEpochSecond(now);
        }
        return monthArray;
    }

    /**
     * 获得前num年，如：{"2015",...,"2010"}
     *
     * @param num 多少个年份
     * @return 日期数组
     */
    public static String[] getYearArray(Integer num) {
        String[] yearArray = new String[num];
        long now = getInt();
        for (int i = 0; i < num; i++) {
            now = getFirstDateOfPreviousYear(now);
            yearArray[i] = getString(now, SDFYears);
        }
        return yearArray;
    }

    /**
     * 计算两个时间 相差天数
     * 这个计算会存在问题 假如 2021-03-12减去2021-03-11计算结果不是1
     *
     * @param beforeDayEpochSecond 开始时间 精确到秒的时间戳
     * @param lastDayEpochSecond   结束时间 精确到秒的时间戳
     * @return 相差多少天数
     */
    @Deprecated
    public static int betweenDays(long beforeDayEpochSecond, long lastDayEpochSecond) {
        return Math.toIntExact((lastDayEpochSecond - beforeDayEpochSecond) / (24 * 3600));
    }
    /**
     * 计算两个时间 相差天数
     *
     * @param beforeDayEpochSecond 开始时间 精确到秒的时间戳
     * @param lastDayEpochSecond   结束时间 精确到秒的时间戳
     * @return 相差多少天数
     */
    public static int differenceInDays(long beforeDayEpochSecond, long lastDayEpochSecond) {
        beforeDayEpochSecond = PaasDateUtil.getBeforeDayBreak(beforeDayEpochSecond);
        lastDayEpochSecond = PaasDateUtil.getBeforeDayBreak(lastDayEpochSecond);
        long result = lastDayEpochSecond - beforeDayEpochSecond;
        double difference = new BigDecimal(result).divide(new BigDecimal(24 * 3600), 10, BigDecimal.ROUND_HALF_UP).doubleValue();
        if (result < 0D) {
            return (int)Math.floor(difference);
        } else {
            return (int)Math.ceil(difference);
        }

    }
    /**
     * 获取两个时间点之间包含的周
     *
     * @param beforeDayEpochSecond 开始时间 精确到秒的时间戳
     * @param lastDayEpochSecond   结束时间 精确到秒的时间戳
     * @return 包含多少周
     */
    public static int btweenWeeksByMonDay(long beforeDayEpochSecond, long lastDayEpochSecond) {
        if (lastDayEpochSecond < beforeDayEpochSecond) {
            return 0;
        }
        //开始时间时间转为周一
        beforeDayEpochSecond = getWeekMorningInSomeday(beforeDayEpochSecond);

        if (lastDayEpochSecond == getWeekMorningInSomeday(lastDayEpochSecond)) {
            //周一
            if (lastDayEpochSecond == beforeDayEpochSecond) {
                //同一天
                return 1;
            } else {
                return Math.toIntExact((lastDayEpochSecond - beforeDayEpochSecond) / (86400 * 7));
            }
        } else {
            if (beforeDayEpochSecond == getWeekMorningInSomeday(lastDayEpochSecond)) {
                //同一周
                return 1;
            } else {
                return Math.toIntExact((lastDayEpochSecond - beforeDayEpochSecond) / (86400 * 7) + 1);
            }
        }
    }

    /**
     * 获取两个时间点之间包含的月
     *
     * @param beforeDayEpochSecond 开始时间 精确到秒的时间戳
     * @param lastDayEpochSecond   结束时间 精确到秒的时间戳
     * @return 包含多少月份
     */
    public static int btweenMonthByFirst(long beforeDayEpochSecond, long lastDayEpochSecond) {
        if (lastDayEpochSecond < beforeDayEpochSecond) {
            return 0;
        }
        //转成1号
        beforeDayEpochSecond = getFirstDateOfMonthInSomeday(beforeDayEpochSecond);

        Calendar calendarB = Calendar.getInstance();
        calendarB.setTime(new Date(beforeDayEpochSecond * 1000));
        Calendar calendarL = Calendar.getInstance();
        calendarL.setTime(new Date(lastDayEpochSecond * 1000));

        //1号
        if (lastDayEpochSecond == getFirstDateOfMonthInSomeday(lastDayEpochSecond)) {
            if (lastDayEpochSecond == beforeDayEpochSecond) {
                //同一天
                return 1;
            } else {
                int year = calendarL.get(Calendar.YEAR) - calendarB.get(Calendar.YEAR);
                int month = calendarL.get(Calendar.MONTH) - calendarB.get(Calendar.MONTH);
                return year * 12 + month;
            }
        } else {
            if (beforeDayEpochSecond == getFirstDateOfMonthInSomeday(lastDayEpochSecond)) {
                //同一月
                return 1;
            } else {
                int year = calendarL.get(Calendar.YEAR) - calendarB.get(Calendar.YEAR);
                int month = calendarL.get(Calendar.MONTH) - calendarB.get(Calendar.MONTH);
                return year * 12 + month + 1;
            }
        }
    }

    /**
     * 最后联系时间和当前时间的相差天数
     *
     * @param lastConnectTimeEpochSecond 最后联系时间  精确到秒的时间戳
     * @param nowEpochSecond             当前时间 精确到秒的时间戳
     * @return 相差多少天
     */
    public static int lastConnect(long lastConnectTimeEpochSecond, long nowEpochSecond) {
        int day = Math.toIntExact((nowEpochSecond - lastConnectTimeEpochSecond) / (24 * 3600));
        if (day == 0 && lastConnectTimeEpochSecond < getTodayInt(nowEpochSecond)) {
            return 1;
        }
        return day;
    }

    /**
     * 最后联系时间格式化显示
     *
     * @param lastConnectTimeEpochSecond 最后联系时间  精确到秒的时间戳
     * @return 最后联系时间格式化显示
     * @author GuoJun.HU
     * @date 2019/2/27 13:47
     * @since V1.0
     */
    public static String getLastConnectTimeStr(Long lastConnectTimeEpochSecond) {
        String lastConnectTimeStr;
        if (lastConnectTimeEpochSecond == null || lastConnectTimeEpochSecond == 0) {
            lastConnectTimeStr = "";
        } else {
            Long timeDifference = getInt() - lastConnectTimeEpochSecond;
            if (timeDifference/60 == 0) {
                // 1分钟内
                lastConnectTimeStr = I18nMessageUtil.getMessage(DateConstant.JUST);
            } else if (timeDifference/60 < 60) {
                // 1小时内
                lastConnectTimeStr = timeDifference/60 + I18nMessageUtil.getMessage(DateConstant.MINUTE_AGO);
            } else if (timeDifference/3600 < 5) {
                // 5小时内
                lastConnectTimeStr = timeDifference/3600 + I18nMessageUtil.getMessage(DateConstant.HOUR_AGO);
            } else if (getTodayInt() < lastConnectTimeEpochSecond) {
                // 超过5小时但在今日内
                lastConnectTimeStr = TimeTypeEnum.DAY.getName() + getStringEpochSecond(lastConnectTimeEpochSecond, SDFHour_Minutes);
            } else if (timeDifference/86400 < 3) {
                return I18nMessageUtil.getMessage(DateConstant.WITHIN_THREE_DAY);
            } else if (timeDifference/86400 < 7) {
                return I18nMessageUtil.getMessage(DateConstant.WITHIN_A_WEEK);
            } else if (timeDifference/86400 < 14) {
                return I18nMessageUtil.getMessage(DateConstant.WITHIN_TWO_WEEK);
            } else if (timeDifference/86400 < 30) {
                return I18nMessageUtil.getMessage(DateConstant.WITHIN_A_MONTH);
            } else if (timeDifference/86400 < 60) {
                return I18nMessageUtil.getMessage(DateConstant.WITHIN_TWO_MONTH);
            } else if (timeDifference/86400 < 90) {
                return I18nMessageUtil.getMessage(DateConstant.WITHIN_THREE_MONTH);
            } else {
                lastConnectTimeStr = getStringEpochSecond(lastConnectTimeEpochSecond, SDFYMDHM);
            }
        }
        return lastConnectTimeStr;
    }

    /**
     * 计算客户未联系天数，如果未联系过，则返回“未联系”，否则返回“n天”
     * @param lastConnectTimeEpochSecond 最后联系时间戳
     * @return java.lang.String
     * @author zcp
     * @date 2019/6/3 14:39
     * @since v1.0
     * @version v1.0
     */
    public static String getLastConnectDay(Long lastConnectTimeEpochSecond) {
        String lastConnectTimeStr;
        if (lastConnectTimeEpochSecond == null || lastConnectTimeEpochSecond == 0) {
            lastConnectTimeStr = I18nMessageUtil.getMessage(StringConstant.NEVER_CONNECT);
        } else {
            int flag = DateTimeUtil.lastConnect(lastConnectTimeEpochSecond, DateTimeUtil.getInt());
            lastConnectTimeStr = flag + I18nMessageUtil.getMessage(CommonConstant.DAY);
        }
        return lastConnectTimeStr;
    }

    /**
     * 格式化最近更新时间
     *
     * @param lastConnectTimeEpochSecond 最后联系时间  精确到秒的时间戳
     * @param nowEpochSecond             当前时间
     * @return JSONObject
     */
    public static JSONObject formatLastConnectTime(Long lastConnectTimeEpochSecond, Long nowEpochSecond) {
        JSONObject lastConnect = new JSONObject();
        if (Objects.isNull(lastConnectTimeEpochSecond) || lastConnectTimeEpochSecond == 0) {
            lastConnect.put("lastConnectTimeStr", I18nMessageUtil.getMessage(StringConstant.NEVER_CONNECT));
            lastConnect.put("lastConnectTimeDay", 0);
            return lastConnect;
        }
        if (Objects.isNull(nowEpochSecond)) {
            nowEpochSecond = DateTimeUtil.getInt();
        }
        Integer time = DateTimeUtil.lastConnect(lastConnectTimeEpochSecond, nowEpochSecond);
        if (time <= 0) {
            lastConnect.put("lastConnectTimeStr", I18nMessageUtil.getMessage(I18nStringConstant.CONTACTED_TODAY));
        } else if (time <= TimeConstant.SECONDS_PER_MONTH) {
            lastConnect.put("lastConnectTimeStr", time + I18nMessageUtil.getMessage(I18nStringConstant.DAYS_NOT_CONNECTED));
        } else if (time <= TimeConstant.SECONDS_PER_MONTH * 2) {
            lastConnect.put("lastConnectTimeStr", I18nMessageUtil.getMessage(I18nStringConstant.NOT_CONTACTED_MORE_ONE_MONTH));
        } else if (time <= TimeConstant.SECONDS_PER_MONTH * 3) {
            lastConnect.put("lastConnectTimeStr", I18nMessageUtil.getMessage(I18nStringConstant.NOT_CONTACTED_MORE_TWO_MONTH));
        } else {
            lastConnect.put("lastConnectTimeStr", I18nMessageUtil.getMessage(I18nStringConstant.NOT_CONTACTED_MORE_THREE_MONTH));
        }
        lastConnect.put("lastConnectTimeDay", time);
        return lastConnect;
    }

    /**
     * 获取某时间点的这一年的第month个月的月初
     *
     * @param epochSecond 精确到秒的时间戳
     * @param month       几月
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 13:49
     * @since V1.0
     */
    public static final long getFirstDateOfMonth(Long epochSecond, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR), month - 1, 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取某时间点的这一年的第month个月的月末
     *
     * @param epochSecond 精确到秒的时间戳
     * @param month       几月
     * @return 精确到秒的时间戳
     * @author GuoJun.HU
     * @date 2019/2/27 13:49
     * @since V1.0
     */
    public static final long getEndDateOfMonth(Long epochSecond, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        calendar.set(calendar.get(Calendar.YEAR), month, 1, 0, 0, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取excel里的时间格式，一般是1900年以来的天数 ，50000以内
     * 获取excel中的格式各样的时间格式，统一格式解析
     *
     * @param date Excel表格中填写的值
     * @return 精确到秒的时间戳
     */
    public static Long getExcelTime(String date) {
        if (StringUtil.isEmpty(date)) {
            return 0L;
        }
        long result = 0L;
        Long dateInt = StringUtil.StringToLong(date);
        if (dateInt != null ) {
           return dateInt;
        } else {
            //excel中时间不是数字
            if (date.contains(StringConstant.POINT)) {
                //2015.09.01格式
                date = date.replace(StringConstant.POINT, "-");
            }
            if (date.contains("/")) {
                //2015/09/01格式
                date = date.replace("/", "-");
            }
            if (date.length() == 8 && !date.contains("-")) {
                //20150901格式
                date = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8);
            }
            if (date.contains("-")) {
                try {
                    if (date.length() > 10) {
                        result = DateTimeUtil.getInt(date, new SimpleDateFormat("yyyy-MM-dd HH:mm"));
                    } else {
                        result = DateTimeUtil.getInt(date, new SimpleDateFormat("yyyy-MM-dd"));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    result = 0;
                }

            }
        }
        return result;
    }

    /**
     * 获取某个时间的半年开始时间
     * 比如，someday在前6个月，则该方法得到someday所在年的1月1日0点
     * someday在后6个月，则该方法得到someday所在年的6月1日0点
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author chuanpeng.zhang
     * @time 2016-8-4 上午10:59:20
     */
    public static Long getHalfYearStartTime(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        int someMonth = calendar.get(Calendar.MONTH) + 1;

        Long startTime = null;
        if (someMonth >= 1 && someMonth <= 6) {
            startTime = getFirstDateOfMonth(epochSecond, 1);
        } else if (someMonth >= 7 && someMonth <= 12) {
            startTime = getFirstDateOfMonth(epochSecond, 7);
        }

        return startTime;
    }

    /**
     * 获取某个时间的半年结束时间
     * 比如，someday在前6个月，则该方法得到someday所在年的6月30日24点--即7月1日0点
     * someday在后6个月，则该方法得到someday所在年的12月31日24点--即下年的1月1日0点
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 精确到秒的时间戳
     * @author chuanpeng.zhang
     * @time 2016-8-4 上午11:01:01
     */
    public static Long getHalfYearEndTime(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date((long) (epochSecond) * 1000));
        int someMonth = calendar.get(Calendar.MONTH) + 1;

        Long endTime = null;
        if (someMonth >= 1 && someMonth <= 6) {
            endTime = getEndDateOfMonth(epochSecond, 6);
        } else if (someMonth >= 7 && someMonth <= 12) {
            endTime = getEndDateOfMonth(epochSecond, 12);
        }

        return endTime;
    }

    /**
     * 输入原始Unix_Timestamp秒数，计算到今年的同一天
     * 如得出用户今年的生日
     *
     * @param epochSecond 用户生日 Unix_Timestamp 精确到秒的时间戳
     * @return 用户今年的生日 Unix_Timestamp 精确到秒的时间戳
     */
    public static long formatOriginDay2ThisYear(long epochSecond) {
        String bornDateStr = getString(new Date(epochSecond * 1000L), SDFDate);
        String todayDateStr = getString(new Date(), SDFDate);
        return getInt(todayDateStr.substring(0, 4) + bornDateStr.substring(4), SDFDate);
    }

    /**
     * 输入原始Unix_Timestamp秒数，计算到今年的年数
     * 如计算用户的年龄
     *
     * @param epochSecond 精确到秒的时间戳
     * @return 年龄
     */
    public static int checkAge(long epochSecond) {
        Date originDate = DateTimeUtil.getDate(epochSecond);
        Calendar born = Calendar.getInstance();
        Calendar birthday = Calendar.getInstance();

        born.setTime(originDate);
        birthday.setTime(new Date());

        // 年龄
        return birthday.get(Calendar.YEAR) - born.get(Calendar.YEAR);
    }

    /**
     * 将秒数化为分钟
     *
     * @param epochSecond 秒数 精确到秒的时间戳
     * @return 分钟（向上取整）
     * @author 章华隽
     * 创建时间：2018/1/30 下午2:15
     * 修改时间：
     * @version 3.17
     * @since 3.17
     */
    public static Integer seconds2Minutes(Long epochSecond) {
        int minute;
        if (epochSecond == null) {
            minute = 0;
        } else {
            int temp = Math.toIntExact(epochSecond % 60);
            temp = temp > 0 ? 1 : 0;
            minute = Math.toIntExact(epochSecond / 60 + temp);
        }
        return minute;
    }

    /**
     * 校验时间字符串是否合法，合法则返回转化得到的10位Timestamp
     *
     * @param dateStr 等待校验的时间字符串
     * @return 10位Timestamp  精确到秒的时间戳
     * @throws ParseException 时间格式转化异常
     * @author 章华隽
     * 创建时间： 2017/9/20 下午3:32
     * 修改时间：
     * @since 3.13
     */
    public static long verifyDate(String dateStr) throws ParseException {
        return verifyDate(dateStr, null);
    }

    /**
     * 校验时间字符串是否合法，合法则返回转化得到的10位Timestamp
     *
     * @param dateStr 等待校验的时间字符串
     * @param format  时间字符串转换器
     * @return 10位Timestamp 精确到秒的时间戳
     * @throws ParseException 时间格式转化异常
     * @author 章华隽
     * 创建时间： 2017/9/20 下午3:32
     * 修改时间：
     * @since 3.13
     */
    public static long verifyDate(String dateStr, SimpleDateFormat format) throws ParseException {
        if (StringUtil.isEmpty(dateStr)) {
            throw new ParseException("", 0);
        }
        if (format == null) {
            format = SDFDate;
        }
        // 指定日期格式为四位年/两位月份/两位日期，注意yyyy/MM/dd区分大小写；
        try {
            return getInt(format.parse(dateStr));
        } catch (ParseException e) {
            throw e;
        }
    }

    /**
     * [yyyy-MM-dd格式]日期 +1天
     * 例：dateStr="2018-01-31"，经过该方法处理，则返回"2018-02-01"
     *
     * @param dateStr [yyyy-MM-dd格式]，要加一天的日期
     * @return [yyyy-MM-dd格式]日期
     * @author lujiang
     * 创建时间：when
     * 修改时间：2018-1-31 上午9:48:37 by zcp
     * @since 合同列表改造
     */
    public static String plusOneDay(String dateStr) {
        Date d = DateTimeUtil.getDate(dateStr, SDFDate);
        if (d == null) {
            return "";
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);
        //加一天
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        return getDateString(calendar.getTime());
    }

    /**
     * [yyyy-MM-dd格式]日期 +1天
     * 例：dateStr="2018-01-31"，经过该方法处理，则返回"2018-02-01"
     *
     * @param dateStr [yyyy-MM-dd格式]，要加一天的日期
     * @return [yyyy-MM-dd格式]日期
     * @author lujiang
     * 创建时间：when
     * 修改时间：2018-1-31 上午9:48:37 by zcp
     * @since 合同列表改造
     */
    public static String delOneDay(String dateStr) {
        Date d = DateTimeUtil.getDate(dateStr, SDFDate);
        if (d == null) {
            return "";
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);
        //减一天
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return getDateString(calendar.getTime());
    }

    /**
     * 获取当月的 天数
     *
     * @return 当月总天数
     * @author 章华隽
     * 创建时间：2018/3/28 下午2:52
     * 修改时间：
     * @version 3.20
     * @since 3.20
     */
    public static int getCurrentMonthDays() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.DATE, 1);
        c.roll(Calendar.DATE, -1);
        return c.get(Calendar.DATE);
    }

    /**
     * 获得下个月的天数
     *
     * @return 下个月的天数
     */
    public int getMaxDayByYearMonth() {
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 1);
        c.set(Calendar.DATE, 1);
        c.roll(Calendar.DATE, -1);
        return c.get(Calendar.DATE);
    }

    /**
     * 获得上个月的天数
     * @return
     */
    public static int getMaxDayByLastMonth(){
        Calendar c = Calendar.getInstance();
        // 设置为当前月第一天
        c.set(Calendar.DAY_OF_MONTH,1);
        // -1天得到上月最后一天
        c.add(Calendar.DAY_OF_MONTH, -1);
        return c.get(Calendar.DATE);
    }

    /**
     * 获取今天是几号
     *
     * @return 今天几号
     * @author 章华隽
     * 创建时间：2018/3/28 下午2:57
     * 修改时间：
     * @version 3.20
     * @since 3.20
     */
    public static int getTodayNumInMonth() {
        Calendar c = Calendar.getInstance();
        return c.get(Calendar.DATE);
    }

    /**
     * 获取当前时间的月份有几天
     */
    public static int getDaysOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取当前年份的天数
     */
    public static int getCurrentYearDays(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        Calendar c = Calendar.getInstance();
        c.set(Calendar.YEAR, calendar.get(Calendar.YEAR));
        return c.getActualMaximum(Calendar.DAY_OF_YEAR);
    }

    /**
     * 传入一个时间（epochSecond），计算该时间在财年的第几周
     * 【如果周一在当前月份，则当周归属为该月，否则则归属到上一个月】
     *
     * @param startMonthTimeEpochSecond 财年起始月第一天的时间戳 精确到秒的时间戳
     * @param epochSecond               时间戳 精确到秒的时间戳
     * @return someTime所在财年的第几周，如果是负数，则代表上一个财年的第几周
     * @author 朱乾徽
     * @date 2018/7/5 10:02
     */
    public static int getWeekNum(Long startMonthTimeEpochSecond, Long epochSecond) {
        //财年月第一周
        long weekNum;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(startMonthTimeEpochSecond * 1000));
        //财年起始月第一天为周几
        int week = calendar.get(Calendar.DAY_OF_WEEK);
        //因为按照欧美，周日为一周第一天，所以为第几天需要进行判断
        if (week == 1) {
            week = 7;
        } else {
            week--;
        }
        //时间戳时间为周四时时间点为周四的0时0分0秒，所以实际时间需要减少一天
        if (week == 1) {
            //如果起始第一天为周一的话，第一周为当前财年的
            weekNum = (epochSecond - startMonthTimeEpochSecond + (week - 1) * 3600 * 24) / 604800 + 1;
        } else {
            weekNum = (epochSecond - startMonthTimeEpochSecond + (week - 1) * 3600 * 24) / 604800;
        }
        //如果当前的时间所属周在上一财年返回上一财年的最后一周为第几周(负数)
        if (weekNum == 0) {
            weekNum = -getWeekNum(getFirstDateOfLastYear(startMonthTimeEpochSecond), epochSecond);
        }
        return Math.toIntExact(weekNum);
    }

    /**
     * 根据财年月的初始时间(startMonthTimeEpochSecond)，获取第weekNum的周一0点的时间
     *
     * @param startMonthTimeEpochSecond 财年起始月第一天的时间戳 精确到秒的时间戳
     * @param weekNum                   第几周
     * @return 第weekNum周的周一0点的时间戳 精确到秒的时间戳
     * @author 朱乾徽
     * @date 2018/7/5 10:02
     */
    public static long getWeekStartTime(Long startMonthTimeEpochSecond, int weekNum) {
        //第weekNum周的周一0点
        long weekStartTime;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(startMonthTimeEpochSecond * 1000));
        //财年起始月第一天为周几
        int week = calendar.get(Calendar.DAY_OF_WEEK);
        //因为按照欧美，周日为一周第一天，所以为第几天需要进行判断
        if (week == 1) {
            week = 7;
        } else {
            week--;
        }
        if (weekNum > 0) {
            //如果财年第一天为周一，第一周为当前财年的
            if (week == 1) {
                weekStartTime = startMonthTimeEpochSecond + (weekNum - 1) * 604800 - (week - 1) * 3600 * 24;
            } else {
                weekStartTime = startMonthTimeEpochSecond + weekNum * 604800 - (week - 1) * 3600 * 24;
            }
        } else {
            //如果weekNum为负数时，为上一财年的时间，获取上一财年的第weekNum的时间戳
            weekStartTime = getWeekStartTime(getFirstDateOfLastYear(startMonthTimeEpochSecond), -weekNum);
        }
        return weekStartTime;
    }

    /**
     * 获取someday属于财年的第几季度
     *
     * @param epochSecond 某一天 精确到秒的时间戳
     * @param startMonth  财年起始月
     * @author cp.zhang
     * 创建时间：2017-7-12
     * 修改时间：
     * @since 3.9
     */
    public static int getSeason4Fiscal(Long epochSecond, int startMonth) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        int month = calendar.get(Calendar.MONTH);
        //calendar是从0开始的
        month++;

        int season = 0;
        int beginMonth = startMonth;
        for (int i = 1; i <= 12; i++) {
            if (month == beginMonth) {
                //该值小于等于1代表第一个季度，以此类推
                double tempSeason = i / 3.0;
                if (tempSeason <= 1) {
                    season = 1;
                } else if (tempSeason <= 2) {
                    season = 2;
                } else if (tempSeason <= 3) {
                    season = 3;
                } else if (tempSeason <= 4) {
                    season = 4;
                }
                break;
            }

            beginMonth++;
            //如果大于12，则从新从1月开始
            beginMonth = (beginMonth > 12) ? 1 : beginMonth;
        }
        return season;
    }

    /**
     * 判断当前月是在哪一个财年，例，当前7月，而财年周期是当年9月至次年8月，说明当前7月还在上一个财年
     *
     * @param startMonth 财年起始月
     * @return 当前月所在财年
     * @version 3.11.3
     * @author cp.zhang
     * 创建时间：2017-7-15 下午3:31:55
     * 修改时间：2017-8-31 下午 by zcp 只要财年起始月不为1月，则当前财年为自然年+1
     * @since 3.9
     */
    public static Integer getFiscalYear4Now(int startMonth) {
        Long nowTime = getInt();
        //当前年
        Integer year = getYear4Someday(nowTime);
        //当前月
        Integer month = getMonth4Someday(nowTime);
        return getFiscalYearByMonth(year, month, startMonth);
    }

    /**
     * 根据月份判断year年所在的财年年份（只处理筛选自然时间的情况）
     *
     * @param year       筛选的自然年
     * @param month      筛选的自然月
     * @param startMonth 财年起始月份
     * @return year年所在的财年年份
     * @version performance-v1.0
     * @author chuanpeng.zhang
     * 创建时间：2018年10月16日 下午4:29:14
     * 修改时间：
     * @since performance-v1.0
     */
    public static Integer getFiscalYearByMonth(Integer year, Integer month, int startMonth) {
        Integer fiscalYear = year;
        if (startMonth != 1 && month >= startMonth) {
            fiscalYear = year + 1;
        }
        return fiscalYear;
    }

    /**
     * 获取筛选时间所在的财年年份
     * 注：
     * （1）该方法只适用于筛选了年度时，得到筛选的财年年份
     * （2）当前系统财年所在年份即endTime所在的年份。
     *
     * @param endTimeEpochSecond 筛选截止时间 精确到秒的时间戳
     * @return 财年
     * @version v3.19
     * @author cp.zhang
     * 创建时间：2018-3-13 下午3:23:32
     * 修改时间：
     * @since v3.19
     */
    public static Integer getFiscalYearByTime(Long endTimeEpochSecond) {
        return StringUtil.toInt(DateTimeUtil.getYear(endTimeEpochSecond - 86400));
    }

    /**
     * 判断month月在财年内属于财年第几月
     *
     * @param startMonth 财年起始月
     * @param month      自然月份
     * @return month月在财年的第几月
     * @version performance-v1.0
     * @author chuanpeng.zhang
     * 创建时间：2018年9月5日 上午9:45:03
     * 修改时间：
     * @since performance-v1.0
     */
    public static Integer getFiscalMonth(int startMonth, int month) {
        if (startMonth == 1) {
            //起始月为1月，则跟自然月一致
            return month;
        }
        return (month + 12 - startMonth) % 12 + 1;
    }

    /**
     * 根据财年年份和财年月份获取出自然年份
     *
     * @param fiscalYear  财年年份
     * @param fiscalMonth 财年月份
     * @param startMonth  财年起始月份
     * @return 自然年
     * @version performance-v1.0
     * @author chuanpeng.zhang
     * 创建时间：2018年10月17日 下午7:54:46
     * 修改时间：
     * @since performance-v1.0
     */
    public static Integer getNormalYearByFiscalYear(Integer fiscalYear, Integer fiscalMonth, int startMonth) {
        Integer year = fiscalYear;
        Integer month = getNormalMonthByFiscalMonth(fiscalMonth, startMonth);
        if (startMonth != 1 && month >= startMonth) {
            year = fiscalYear - 1;
        }
        return year;
    }

    /**
     * 根据财年月份和财年起始月，得到自然月份
     *
     * @param fiscalMonth 财年月份
     * @param startMonth  财年起始月份
     * @return 自然月份
     * @version performance-v1.0
     * @author chuanpeng.zhang
     * 创建时间：2018年10月17日 下午8:27:26
     * 修改时间：
     * @since performance-v1.0
     */
    public static Integer getNormalMonthByFiscalMonth(int fiscalMonth, int startMonth) {
        if (startMonth == 1) {
            //起始月为1月，则跟自然月一致
            return fiscalMonth;
        }
        int month = (startMonth + fiscalMonth + 12) % 12 - 1;
        month = (month == 0) ? 12 : month;
        return month;
    }

    /**
     * 将秒数转换为时分秒，
     *
     * @param epochSecond 精确到秒的时间戳
     * @return X时X分X秒
     */
    public static String secondToTime(Long epochSecond) {
        //剩余秒数
        epochSecond = epochSecond % 86400;
        //转换小时
        long hours = epochSecond / 3600;
        //剩余秒数
        epochSecond = epochSecond % 3600;
        //转换分钟
        long minutes = epochSecond / 60;
        //剩余秒数
        epochSecond = epochSecond % 60;
        return hours + "时" + minutes + "分" + epochSecond + "秒";
    }

    /**
     * 将秒数转换为时分秒，
     *
     * @param epochSecond 精确到秒的时间
     * @return X时X分X秒
     */
    public static String secondToTime(Integer epochSecond) {
        //转换小时
        long hours = epochSecond / 3600;
        //剩余秒数
        epochSecond = epochSecond % 3600;
        //转换分钟
        long minutes = epochSecond / 60;
        //剩余秒数
        epochSecond = epochSecond % 60;
        return hours + "时" + minutes + "分" + epochSecond + "秒";
    }

    /**
     * 将指定日期加/减指定月数获取日期
     * @param value 秒级时间戳
     * @param intervalMonth 间隔月份
     * @return 某个月最大天数
     */
    public static int getIntByIntervalMonth(Long value, Integer intervalMonth) {
        Calendar calendar = Calendar.getInstance();
        //设置起时间
        Date date = getDate(value);
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, intervalMonth);
        int thisYearDay = DateUtil.getInt(calendar.getTime());
        return thisYearDay;
    }
    /**
     * 将指定日期加/减指定年数获取日期
     * @param value 秒级时间戳
     * @param intervalYear 指定年数
     * @return 某个月最大天数
     */
    public static int getIntByIntervalYear(Long value, Integer intervalYear) {
        Calendar calendar = Calendar.getInstance();
        //设置起时间
        Date date = getDate(value);
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, intervalYear);
        int thisYearDay = DateUtil.getInt(calendar.getTime());
        return thisYearDay;
    }

    /**
     * 计算两个时间 相差几小时
     * @param beforeDay
     * @param lastDay
     * @return
     */
    public static Long betweenHours(Long beforeDay, Long lastDay) {
        Long day = (lastDay - beforeDay) / 3600;
        return day;
    }
    /**
     * 计算两个时间 相差多少分钟
     * @param beforeDay
     * @param lastDay
     * @return
     */
    public static Long betweenMinutes(Long beforeDay, Long lastDay) {
        Long day = (lastDay - beforeDay) / 60L;
        return day;
    }

    public static boolean isSDFDate(String date) {
        try {
            SDFDate.parse(date);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 获取当天的开始时间
     *
     * @param epochSecond  精确到秒的时间戳
     * @author chenshan
     * @return epochSecond 精确到秒的时间戳
     */
    public static Long getStartOfDay(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DATE);
        calendar.set(year, month, day, 0, 0, 0);
        return calendar.getTimeInMillis()/1000;
    }

    /**
     * 获取当天的结束时间
     *
     * @param epochSecond 精确到秒的时间戳
     * @author chenshan
     * @return epochSecond 精确到秒的时间戳
     */
    public static Long getEndOfDay(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DATE);
        calendar.set(year, month, day, 23, 59, 59);
        return calendar.getTimeInMillis()/1000;
    }

    /**
     * 获取某个时间的0秒
     *
     * @param epochSecond 精确到秒的时间戳
     * @return epochSecond 精确到秒的时间戳
     */
    public static long getStartOfMinute(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DATE);
        int honor = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        calendar.set(year, month, day, honor, minute, 0);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取某个时间的59秒
     *
     * @param epochSecond 精确到秒的时间戳
     * @return epochSecond 精确到秒的时间戳
     */
    public static long getEndOfMinute(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DATE);
        int honor = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        calendar.set(year, month, day, honor, minute, 59);
        return calendar.getTimeInMillis() / 1000;
    }

    public static String getStartOfHourString(Long epochSecond) {
        return getString(getStartOfHour(epochSecond));
    }

    public static long getStartOfHour(Long epochSecond) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date(epochSecond * 1000));
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DATE);
        int honor = calendar.get(Calendar.HOUR_OF_DAY);
        calendar.set(year, month, day, honor, 0, 0);
        return calendar.getTimeInMillis();
    }

    /**
     *获取过了****天的当天结束时间
     */
    public static Long getSeveralDaysLaterEndTime(Long epochSecond, Integer days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date((epochSecond + TimeConstant.SECONDS_PER_DAY * days) * 1000));
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DATE);
        calendar.set(year, month, day, 23, 59, 59);
        return calendar.getTimeInMillis()/1000;
    }

    /**
     * 获取过了****天的开始时间
     * @param epochSecond
     * @author chenshan
     * @return
     */
    public static Long getSeveralDaysLaterBeginTime(Long epochSecond, Integer days) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date((epochSecond + TimeConstant.SECONDS_PER_DAY * days) * 1000));
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DATE);
        calendar.set(year, month, day, 0, 0, 0);
        return calendar.getTimeInMillis()/1000;
    }

    /**
     *获取某个时间是不是当天
     */
    public static Boolean isToday(Long epochSecond) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date(epochSecond*1000);
        return simpleDateFormat.format(new Date()).equals(simpleDateFormat.format(date));
    }

    /**
     * 获取 指定时间 前/后 n 年/月/日 时间戳
     * @param value 指定时间
     * @param interval 差值n
     * @param calendarType 日期类型
     * @return long 秒级时间戳
     * @author xinpeng.jiang
     * @date 2021/10/13 15:21
     * @version 1.0
     */
    public static long getTimestampByCalendarType(long value, int interval, int calendarType) {
        Calendar calendar = Calendar.getInstance();
        Date date = getDateEpochSecond(value);
        calendar.setTime(date);
        calendar.add(calendarType, interval);
        return calendar.getTimeInMillis() / 1000;
    }

    /**
     * 获取excel里的时间格式，一般是1900年以来的天数 ，50000以内
     * 获取excel中的格式各样的时间格式，统一格式解析
     *
     * @param date Excel表格中填写的值
     * @return 精确到秒的时间戳
     */
    public static Long getExcelDate(String date) {
        long result = 0L;
        if (StringUtil.isEmpty(date)) {
            return result;
        }
        try {
            // 先判断是否是剑
            String pattern = "^(\\d{4}(-)\\d{1,2}(-)\\d{1,2})$";
            boolean matches = Pattern.matches(pattern, date);
            if (!matches) {
                pattern = "^(\\d{4}(/)\\d{1,2}(/)\\d{1,2})$";
                matches = Pattern.matches(pattern, date);
            }
            if (!matches) {
                pattern = "(\\d{4}[.]\\d{1,2}[.]\\d{1,2})$";
                matches = Pattern.matches(pattern, date);
            }
            if (!matches) {
                return result;
            }
            // 截取年、月、日(上面正则表达式通过说明都是数字)
            int year = Integer.parseInt(date.substring(0, 4));
            int moth = Integer.parseInt(date.substring(5, 7));
            int day = Integer.parseInt(date.substring(8, 10));
            if (!checkDate(year, moth, day)) {
                return result;
            }
            String[] parsePatterns = new String[]{
                    "yyyy-MM-dd", "yyyy.MM.dd", "yyyy/MM/dd"
            };
            result = DateUtil.getInt(DateUtils.parseDate(date, parsePatterns));
        } catch (ParseException e) {
            return result;
        }


        return result;
    }

    /**
     * 判断年是否真正确
     * 需要大于1970年
     *
     * @param year 年
     * @return 是否正确
     */
    private static Boolean isYear(Integer year) {
        if (Objects.isNull(year) || year < 0) {
            return false;
        }
        return year > 1970;
    }

    /**
     * 判断月是否真正确
     * 需要大于等于1且小于等于12
     *
     * @param moth 月
     * @return 是否正确
     */
    private static Boolean isMoth(Integer moth) {
        if (Objects.isNull(moth) || moth < 0) {
            return false;
        }
        return moth >= 1 && moth <= 12;
    }

    /**
     * 判断日期的年月日是否正确
     *
     * @param year 年
     * @param moth 月
     * @param day  日
     * @return 是否正确
     */
    private static Boolean checkDate(Integer year, Integer moth, Integer day) {
        if (!isYear(year) || !isMoth(moth)) {
            return false;
        }
        List<Integer> bigMoth = Arrays.asList(1, 3, 5, 7, 8, 10, 12);
        List<Integer> littleMoth = Arrays.asList(4, 6, 9, 11);
        if (bigMoth.contains(moth) && (day < 1 || day > 31)) {
            return false;
        }
        if (littleMoth.contains(moth) && (day < 1 || day > 30)) {
            return false;
        }

        if (Objects.equals(moth, 2)) {
            if (leapYear(year) && (day < 1 || day > 29)) {
                return false;
            }
            if (!leapYear(year) && (day < 1 || day > 28)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 是否闰年
     *
     * @param year 年
     * @return 是否闰年
     */
    private static Boolean leapYear(Integer year) {
        if (Objects.isNull(year) || year < 0) {
            return false;
        }
        return Objects.equals(year % 4, 0) || Objects.equals(year % 400, 0);
    }

    /**
     * 获取当前时间到当晚23点59分59秒之间的秒数
     * @return 精确到秒的时间戳
     */
    public static Long getUntilTodayDeadline(){
        Long now = DateUtil.getNow();
        Long endOfDay = DateTimeUtil.getEndOfDay(now);
        return endOfDay - now;
    }

    public static void main(String[] args) {
        System.out.println(DateTimeUtil.getTodayInt());
        System.out.println(getSeveralDaysLaterEndTime(DateTimeUtil.getTodayInt(), 1));
        String nowTimeStr = DateTimeUtil.getStringEpochSecond(DateTimeUtil.getStartOfHour(DateTimeUtil.getInt())/1000, DateTimeUtil.SDFHour_Minutes);
        String pushTimeStr = DateTimeUtil.getStringEpochSecond((DateTimeUtil.getStartOfHour(DateTimeUtil.getInt())/1000)+60*5, DateTimeUtil.SDFHour_Minutes);
        System.out.println(nowTimeStr);
        System.out.println(pushTimeStr);
        System.out.println(getSeason(Calendar.getInstance().getTimeInMillis()/1000));
        System.out.println(getFirstDateOfSeason(Calendar.getInstance().getTimeInMillis()/1000));
        System.out.println(getLastDateOfSeason(Calendar.getInstance().getTimeInMillis()/1000));
        System.out.println(getFirstDateOfLastSeason(Calendar.getInstance().getTimeInMillis()/1000));
        System.out.println(getLastDateOfLastSeason(Calendar.getInstance().getTimeInMillis()/1000));
        System.out.println("--------------------------------");
        System.out.println(DateTimeUtil.getWeekMorningInSomeday(getInt()));
        System.out.println(DateTimeUtil.getSundayInSomeday(getInt()) - 1);
        System.out.println(DateTimeUtil.getFirstDateOfMonthInSomeday(getInt()));
        System.out.println(DateTimeUtil.getLastDateOfThisMonthInSomeday(getInt()));
        long firstDateOfMonthInSomeday1 = DateTimeUtil.getWeekMorningInSomeday(getInt());
        long lastDateOfThisMonthInSomeday1 = DateTimeUtil.getSundayInSomeday(getInt());

        String firstDateOfMonthInSomedayStr1 = DateTimeUtil.getStringEpochSecond(firstDateOfMonthInSomeday1, DateTimeUtil.SDFDate);
        String lastDateOfThisMonthInSomedayStr1 = DateTimeUtil.getStringEpochSecond(lastDateOfThisMonthInSomeday1, DateTimeUtil.SDFDate);
        System.out.println(firstDateOfMonthInSomedayStr1);
        System.out.println(lastDateOfThisMonthInSomedayStr1);


        long firstDateOfMonthInSomeday = DateTimeUtil.getFirstDateOfMonthInSomeday(getInt());
        long lastDateOfThisMonthInSomeday = DateTimeUtil.getLastDateOfThisMonthInSomeday(getInt());

        String firstDateOfMonthInSomedayStr = DateTimeUtil.getStringEpochSecond(firstDateOfMonthInSomeday, DateTimeUtil.SDFDate);
        String lastDateOfThisMonthInSomedayStr = DateTimeUtil.getStringEpochSecond(lastDateOfThisMonthInSomeday, DateTimeUtil.SDFDate);
        System.out.println(firstDateOfMonthInSomedayStr);
        System.out.println(lastDateOfThisMonthInSomedayStr);
    }

    /**
     *解析两个时间戳的时间差 单位为天 精确到小数点后一位
     * @param date1
     * @param date2
     * @return
     */
    public static float getTimeDifferenceByDay(Long date1, Long date2) {
        if (Objects.nonNull(date1) && Objects.nonNull(date2)) {
            float seconds = (float)(date1 - date2);
            //秒转天 小数点后保持一位
        return (float)(Math.round(seconds / 60 / 60 / 24 * 10)) / 10;
        } else {
            return 0;
        }

    }
}
